package com.passion.mq.publish;

import com.passion.mq.annotation.AsyncMQ;
import com.passion.mq.config.RocketMqConfig;
import com.passion.mq.core.MqSender;
import com.passion.mq.transaction.TransactionalMessageService;
import lombok.extern.slf4j.Slf4j;
import org.apache.rocketmq.spring.core.RocketMQTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
import org.springframework.messaging.Message;
import org.springframework.messaging.support.MessageBuilder;
import org.springframework.stereotype.Component;

import java.util.Map;

/**
 * 类描述：rocketmq接口实现类
 *
 * @author ZhuYin
 * @since 2024年12月17日
 */
@AsyncMQ(executor = "asyncLogTaskThreadPool")
@Slf4j
@Component
@ConditionalOnBean(RocketMqConfig.class)
public class RocketMqSender implements MqSender {

    @Autowired(required = false)
    private RocketMQTemplate rocketMQTemplate;

    @Autowired(required = false)
    private TransactionalMessageService transactionalMessageService;

    /**
     * 方法说明：发送普通消息(没有事务控制的)
     *
     * @param topicOrQueue  消息的目标主题或队列名称
     * @param messageBody   要发送的消息内容
     * @author ZhuYin
     * @since 2024年12月30日
     */
    @Override
    public void sendMessage(String topicOrQueue, String messageBody) {
        rocketMQTemplate.asyncSend(topicOrQueue, messageBody, null);
    }

    /**
     * 发送带有额外属性的消息
     *
     * @param topicOrQueue 消息的目标主题或队列名称
     * @param messageBody  要发送的消息内容
     * @param properties   消息的附加属性（如头部信息）
     */
    @Override
    public void sendMessage(String topicOrQueue, String messageBody, Map<String, Object> properties) {
        // 构建消息
        Message<String> message = MessageBuilder
                .withPayload(messageBody)
                .copyHeaders(properties)
                .build();
        // 发送消息
        rocketMQTemplate.syncSend(topicOrQueue, message);
    }

    /**
     * 发送消息到指定的主题/队列
     * 这种是发送事务消息，如果发送消息过程中，本地事务执行失败，则消息会被回滚，最终不会被发送到目标主题/队列中，消费者也无法消费到
     * @param topicOrQueue 消息的目标主题或队列名称
     * @param messageBody  要发送的消息内容
     */

    public void sendTransactionalMessage(String topicOrQueue, String messageBody) {
        transactionalMessageService.sendMessageInTransaction(topicOrQueue, messageBody);
    }

    /**
     * 发送带有额外属性的消息
     * 这种是发送事务消息，如果发送消息过程中，本地事务执行失败，则消息会被回滚，最终不会被发送到目标主题/队列中，消费者也无法消费到
     * @param topicOrQueue 消息的目标主题或队列名称
     * @param messageBody  要发送的消息内容
     * @param properties   消息的附加属性（如头部信息）
     */
    public void sendTransactionalMessage(String topicOrQueue, String messageBody, Map<String, Object> properties) {
        transactionalMessageService.sendMessageInTransactionWithProperties(topicOrQueue, messageBody, properties);
    }


}
